package com.meisen.springboot.controller;

import com.meisen.springboot.entity.Article;
import com.meisen.springboot.exception.ServerException;
import com.meisen.springboot.request.ArticleRequest;
import com.meisen.springboot.response.ResultEntity;
import com.meisen.springboot.service.ArticleService;
import com.meisen.springboot.util.Result;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.List;

/**
 * @author meisen
 * 2018-04-18
 */
@RestController
@RequestMapping("/api/articles")
public class ArticleController {
    private static final String PRODUCE_JSON = "application/json; charset=UTF-8";

    private final ArticleService articleService;


    @Autowired
    public ArticleController(ArticleService articleService) {
        this.articleService = articleService;
    }

    @GetMapping(path = "/list", produces = PRODUCE_JSON)
    public ResultEntity allArticles() {
        List<Article> articles = articleService.findAll();
        return Result.success(articles, null);
    }

    @GetMapping(path = "/tags", produces = {PRODUCE_JSON})
    public ResultEntity allArticleTags() {
        List<String> tags = articleService.getAllArticleTags();
        return Result.success(tags, null);
    }

    @GetMapping(path = "/info", produces = PRODUCE_JSON)
    public ResultEntity article(@RequestParam String id) {
        if (Strings.isBlank(id)) {
            throw new ServerException(1, "文章错误, 没有文章id!");
        }
        Article article = articleService.getArticleById(id);
        if (Article.NO_SUCH_ARTICLE.equals(article.getId())) {
            throw new ServerException(1, "文章错误, 没有该文章!");
        }
        return Result.success(article, null);
    }

    /**
     * 返回已发布文章数量
     *
     * @return 已发布文章数量
     */
    @GetMapping(value = "/count", produces = {PRODUCE_JSON})
    public ResultEntity count() {
        Integer count = articleService.countArticle();
        return Result.success(count, null);
    }

    @RequestMapping(path = "/publish", method = RequestMethod.POST, produces = PRODUCE_JSON)
    public ResultEntity publish(@RequestBody ArticleRequest articleRequest) {
        validateArticleRequest(articleRequest);
        Article publishArticle = getArticle(articleRequest);
        publishArticle.setDate(new Timestamp(System.currentTimeMillis()));
        Article article = articleService.publishArticle(publishArticle);
        return Result.success(article, "发布文章成功");
    }

    /**
     * 热门文章 只返回前5条
     *
     * @return ResultEntity
     */
    @GetMapping(path = "/popular", produces = PRODUCE_JSON)
    public ResultEntity popular(@RequestParam Integer page, @RequestParam Integer size) {
        List<Article> popularArticle = articleService.findPopularArticles(page, size);
        return Result.success(popularArticle, null);
    }

    /**
     * 实现分页
     * 前端功能为先展示前6个 之后每次展示3个
     * 这里发请求初始发(0, 6) 第二次发(2, 3)
     *
     * @param page 请求页数
     * @param size 每页展示条数
     * @return ResultEntity
     */
    @GetMapping(path = "/part", produces = PRODUCE_JSON)
    public ResultEntity pagePart(@RequestParam Integer page, @RequestParam Integer size) {
        return Result.success(articleService.findPartArticles(page, size), "获取文章成功");
    }

    /**
     * 返回tag相关文章
     *
     * @param tag 文章tag
     * @return 统一返回实体类
     */
    @GetMapping(path = "/relative", produces = PRODUCE_JSON)
    public ResultEntity relativeArticles(@RequestParam String tag, @RequestParam Integer page, @RequestParam Integer size) {
        return Result.success(articleService.findRelativeArticles(tag, page, size), null);
    }

    /**
     * 删除文章
     *
     * @param id 需要删除的文章id
     * @return 统一返回实体类
     */
    @GetMapping(path = "/delete", produces = PRODUCE_JSON)
    public ResultEntity deleteArticle(@RequestParam String id) {
        articleService.deleteArticle(id);
        return Result.success(null, "删除文章成功");
    }

    /**
     * 归档
     * @return 统一返回实体类
     */
    @GetMapping(path = "/achieve", produces = PRODUCE_JSON)
    public ResultEntity achieve() {
        return Result.success(articleService.achieveArticle(), null);
    }
    /**
     * 更新文章
     *
     * @param articleRequest 更新文章请求
     * @return 统一返回实体类
     */
    @RequestMapping(path = "/update", method = RequestMethod.POST, produces = PRODUCE_JSON)
    public ResultEntity updateArticle(@RequestBody ArticleRequest articleRequest) {
        validateArticleRequest(articleRequest);
        Article article = articleService.updateArticle(getArticle(articleRequest));
        return Result.success(article, "更新成功");
    }

    /**
     * 递增文章访问量
     *
     * @param id 需要递增的文章id
     * @return 统一返回实体类
     */
    @GetMapping(path = "/visit", produces = PRODUCE_JSON)
    public ResultEntity updateArticleVisit(@RequestParam String id) {
        Integer visit = articleService.getArticleVisit(id);
        articleService.increaseVisit(id, visit + 1);
        return Result.success(null, "更新文章访问量成功");
    }

    /**
     * 点赞
     *
     * @param id 文章id
     * @return 统一返回实体类
     */
    @GetMapping(path = "/compliment/confirm", produces = PRODUCE_JSON)
    public ResultEntity doCompliment(@RequestParam String id) {
        Integer compliment = articleService.getArticleCompliment(id);
        articleService.compliment(id, ++compliment);
        return Result.success(compliment, "点赞成功");
    }

    /**
     * 取消点赞
     *
     * @param id 文章id
     * @return 统一返回实体类
     */
    @GetMapping(path = "/compliment/cancel", produces = PRODUCE_JSON)
    public ResultEntity cancelCompliment(@RequestParam String id) {
        Integer compliment = articleService.getArticleCompliment(id);
        if (compliment > 0) {
            articleService.compliment(id, --compliment);
        }
        return Result.success(compliment, "取消点赞成功");
    }

    private void validateArticleRequest(ArticleRequest request) {
        if (request == null) {
            throw new ServerException(1, "文章错误, 参数校验失败!");
        }
    }

    private Article getArticle(ArticleRequest request) {
        Article article = new Article();
        if (request.getId() != null) {
            article.setId(request.getId());
        }
        article.setContent(request.getContent());
        article.setSummary(request.getSummary());
        article.setTags(request.getTags());
        article.setThumb(request.getThumb());
        article.setTitle(request.getTitle());
        article.setPublish(request.isPublish());
        return article;
    }
}
